The model we are using to fit the data

\[ p_{mult} = \frac{1}{1 + exp(\frac{R_{mult} - R_{add} + \alpha(I_{mult} - I_{add}) + D(M_{add} - M_{mult}) + B}{\sqrt2\sigma})} \]

Are the coefficients significantly different between the short and long horizons?

map2_dfr(
  c("greater", "less", "less"),
  c("difficulty", "information", "temp"),
  ~custom_compare_paired_fits(
  .x, paste0(.y, "_coef"), "replication", F, "rt", "percentile",
  "continuous", "Short horizon, free choice 1", "Long horizon, free choice 1",
  F, F, 0, Inf, "t.test"
  ) %>%
    mutate(coefficient = .y) %>%
    select(coefficient, estimate, statistic, p.value)
)

Coefficient estimates for long vs. short horizons for exploratory and replication data

map(
  c("difficulty", "information", "temp"),
  ~{
    
    my_aggregation = "percentile"
    my_coef = paste0(.x, "_coef")
    my_iv = "rt"

exploratory_short <- here("Analysis", "main_task", "fits.rds") %>%
  read_rds() %>%
  filter(
    batch == "exploratory",
    separate_by_exposure == F,
    iv == my_iv,
    aggregation == my_aggregation,
    continuum == "continuous",
    (free_choice_label == "Short horizon, free choice 1" & equal_exposure == F) |
      (free_choice_label == "Long horizon, free choice 1" & equal_exposure == F)
  ) %>%
  group_by(subid) %>%
  filter(
    min(total_mult_chosen) >= 3,
    max(total_trials - total_mult_chosen) >= 3
  ) %>%
  ungroup() %>%
  mutate(across(c(free_choice_trial), as_factor)) %>%
  arrange(subid, free_choice_label) %>%
  filter(free_choice_label == "Short horizon, free choice 1") %>%
  pull(!!my_coef)

exploratory_long <- here("Analysis", "main_task", "fits.rds") %>%
  read_rds() %>%
  filter(
    batch == "exploratory",
    separate_by_exposure == F,
    iv == my_iv,
    aggregation == my_aggregation,
    continuum == "continuous",
    (free_choice_label == "Short horizon, free choice 1" & equal_exposure == F) |
      (free_choice_label == "Long horizon, free choice 1" & equal_exposure == F)
  ) %>%
  group_by(subid) %>%
  filter(
    min(total_mult_chosen) >= 3,
    max(total_trials - total_mult_chosen) >= 3
  ) %>%
  ungroup() %>%
  mutate(across(c(free_choice_trial), as_factor)) %>%
  arrange(subid, free_choice_label) %>%
  filter(free_choice_label == "Long horizon, free choice 1") %>%
  pull(!!my_coef)

replication_short <- here("Analysis", "main_task", "fits.rds") %>%
  read_rds() %>%
  filter(
    batch == "replication",
    separate_by_exposure == F,
    iv == my_iv,
    aggregation == my_aggregation,
    continuum == "continuous",
    (free_choice_label == "Short horizon, free choice 1" & equal_exposure == F) |
      (free_choice_label == "Long horizon, free choice 1" & equal_exposure == F)
  ) %>%
  group_by(subid) %>%
  filter(
    min(total_mult_chosen) >= 3,
    max(total_trials - total_mult_chosen) >= 3
  ) %>%
  ungroup() %>%
  mutate(across(c(free_choice_trial), as_factor)) %>%
  arrange(subid, free_choice_label) %>%
  filter(free_choice_label == "Short horizon, free choice 1") %>%
  pull(!!my_coef)


replication_long <- here("Analysis", "main_task", "fits.rds") %>%
  read_rds() %>%
  filter(
    batch == "replication",
    separate_by_exposure == F,
    iv == my_iv,
    aggregation == my_aggregation,
    continuum == "continuous",
    (free_choice_label == "Short horizon, free choice 1" & equal_exposure == F) |
      (free_choice_label == "Long horizon, free choice 1" & equal_exposure == F)
  ) %>%
  group_by(subid) %>%
  filter(
    min(total_mult_chosen) >= 3,
    max(total_trials - total_mult_chosen) >= 3
  ) %>%
  ungroup() %>%
  mutate(across(c(free_choice_trial), as_factor)) %>%
  arrange(subid, free_choice_label) %>%
  filter(free_choice_label == "Long horizon, free choice 1") %>%
  pull(!!my_coef)


bind_rows(
  tibble(
    x = "exploratory_short",
    y = exploratory_short
  ),
  
  tibble(
    x = "exploratory_long",
    y = exploratory_long
  ),
  
  tibble(
    x = "replication_short",
    y = replication_short
  ),
  
  tibble(
    x = "replication_long",
    y = replication_long
  )
) %>%
  ggplot(aes(x = x, y = y)) +
  geom_violin() +
  geom_jitter(width =.1) +
  geom_boxplot(width = .1, outlier.shape = NA) +
  theme(legend.position = "none") +
  labs(
    title = .x,
    x = "",
    y = "Coefficent Estimate per Participant"
  )
  }
) %>%
  reduce(`/`)

analysis_combos <- expand.grid(
  pair_compairison = c("greater", "less"),
  coef_of_interest = c("difficulty_coef", "information_coef", "temp_coef"),
  keep_batch = c("exploratory", "replication"),
  keep_separate_by_exposure = F,
  keep_iv = c("rt", "difficulty"),
  keep_aggregation = c("raw", "percentile"),
  keep_continuum = "continuous",
  group_1 = "Short horizon, free choice 1",
  group_2 = "Long horizon, free choice 1",
  min_duration = c(0),
  max_duration = c(Inf),
  type_of_test = c("t.test", "wilcox.test")
) %>%
  mutate(
    group_1_exposure = keep_separate_by_exposure,
    group_2_exposure = keep_separate_by_exposure
  ) %>%
  filter(max_duration > min_duration) %>%
  filter(
    (coef_of_interest == "difficulty_coef" &  pair_compairison == "greater") |
      coef_of_interest != "difficulty_coef" & pair_compairison == "less") %>%
  relocate(type_of_test, .after = last_col()) %>%
  mutate(across(where(is.factor), as.character))

map_dfr(1:nrow(analysis_combos), ~{
  arow <- analysis_combos %>% filter(row_number() == .x)
  
  brow <- custom_compare_paired_fits(
    arow$pair_compairison, arow$coef_of_interest, arow$keep_batch,
    arow$keep_separate_by_exposure, arow$keep_iv, arow$keep_aggregation,
    arow$keep_continuum, arow$group_1, arow$group_2, arow$group_1_exposure,
    arow$group_2_exposure, arow$min_duration, arow$max_duration,
    arow$type_of_test
  )
  
  bind_cols(arow, brow)
  
}) %>%
  arrange(coef_of_interest, keep_batch, -p.value) %>%
  mutate(across(p.value, ~insight::format_p(.x))) %>%
  select(coef_of_interest, keep_batch, p.value, keep_iv, keep_aggregation, type_of_test) %>%
  rename_with(~str_replace_all(.x, "keep_", " "), starts_with("keep_"))

Maybe we should be more vigilant of how long tasks are taking participants?

It doesn’t appear that participants who finish the task quickly are particularly driving the null results (i.e., their coefficient isn’t particulaly large).

map(
    c("max_time_elapsed", "median_choice_time"),
    function(desired_x_axis){
        map(c("exploratory", "replication"), ~
                custom_compare_paired_fits(
                    "greater", "difficulty_coef", .x, F, "rt", "percentile",
                    "continuous", "Short horizon, free choice 1", "Long horizon, free choice 1",
                    F, F, 0, Inf, "t.test", F
                ) %>%
                mutate(difficulty_coef_diff = difficulty_coef_Long - difficulty_coef_Short) %>%
                filter(max_time_elapsed < 100) %>%
                ggplot(aes(!!sym(desired_x_axis), difficulty_coef_diff)) +
                geom_smooth() +
                geom_point() +
                labs(
                    title = paste(
                        .x,
                        "batch,",
                        ifelse(
                            desired_x_axis == "max_time_elapsed",
                            "experiment duration (including instrc)",
                            "average free choice RT"
                        )
                        ),
                    x = ifelse(
                            desired_x_axis == "max_time_elapsed",
                            "Minutes taken to go through entire task",
                            "Average time to make a free choice (in seconds)"
                        ),
                    y = "Difficulty Coefficient"
                )
        ) %>%
            reduce(`/`)
    }
) %>% reduce(`|`)

Average amount of time spent on a free choice, over the course of the task (excluding 32 trials that lasted longer than 2 minutes)

free_choice_df %>%
  mutate(choice_time = choice_time / (60 * 1000)) %>%
  filter(choice_time < 2) %>%
  ggplot(aes(overall_trial, choice_time)) +
  geom_smooth()

Some participants took a massive amount of time (breaks) to complete some of the trials

trials_following_massive_delays

But modeling the results without these participants doesn’t make our results any more significant

custom_compare_paired_fits(
                    "greater", "difficulty_coef", "replication", F, "rt", "percentile",
                    "continuous", "Short horizon, free choice 1", "Long horizon, free choice 1",
                    F, F, 0, Inf, "t.test", T, pcpts_taking_massive_delays
                ) %>%
  pull(p.value)
## [1] 0.05654418

However, if we keep the data from all participants and filter each of these participants by how far along they were in the task, the replication data look more promising

tribble(
  ~"First_x_Trials", ~"Exploratory", ~"Replication",
  20,                0.05671,        0.4849,
  40,                1.053e-05,      0.002351,
  60,                2.019e-05,      0.03906,
  80,                2.729e-07,      0.05509
)

Choice Curves (for replication data)

How much harder mult is than add side and likelihood of choosing mult

Difficulty is measured here by raw baseline RT

input <- list()

input$batch_choice_curve <- "replication"   # "exploratory" "replication"
input$y_var_choice_curve <- "mult" # accuracy bigger_rand bigger_side bigger_rew_exposed_cum_mean bigger_rew_exposed_cum_count bigger_rew_latent bigger_rew_exposed_cum_sd
input$x_raw_or_percent <- "raw" # raw percent
input$choice_combos_choice_curve <- c("Long horizon, free choice 1", "Short horizon, free choice 1") # "Short horizon, free choice 1" "Long horizon, free choice 1"  "Long horizon, free choice 2"  "Long horizon, free choice 3"  "Long horizon, free choice 4"  "Long horizon, free choice 5"
input$x_comparison_group <- "mult" # rew_exposed_cum_sd rew_exposed_cum_mean rew_latent side rand
input$x_comparison_dimension <- "rt" # rew_exposed_cum_mean rew_latent difficulty rand rew_exposed_cum_sd
input$show_CI_choice_curve <- T # F

choice_and_learning_plots("choice_curve")

Difficulty is measured here by raw baseline self-rated difficulty

input$batch_choice_curve <- "replication"   # "exploratory" "replication"
input$y_var_choice_curve <- "mult" # accuracy bigger_rand bigger_side bigger_rew_exposed_cum_mean bigger_rew_exposed_cum_count bigger_rew_latent bigger_rew_exposed_cum_sd
input$x_raw_or_percent <- "raw" # raw percent
input$choice_combos_choice_curve <- c("Long horizon, free choice 1", "Short horizon, free choice 1") # "Short horizon, free choice 1" "Long horizon, free choice 1"  "Long horizon, free choice 2"  "Long horizon, free choice 3"  "Long horizon, free choice 4"  "Long horizon, free choice 5"
input$x_comparison_group <- "mult" # rew_exposed_cum_sd rew_exposed_cum_mean rew_latent side rand
input$x_comparison_dimension <- "difficulty" # rew_exposed_cum_mean rew_latent difficulty rand rew_exposed_cum_sd
input$show_CI_choice_curve <- T # F

choice_and_learning_plots("choice_curve")

Next two plots are same as previous two, except difficulty has been scaled between 1-100 rather than being in raw units

Difficulty is measured here by scaled baseline RT

input$batch_choice_curve <- "replication"   # "exploratory" "replication"
input$y_var_choice_curve <- "mult" # accuracy bigger_rand bigger_side bigger_rew_exposed_cum_mean bigger_rew_exposed_cum_count bigger_rew_latent bigger_rew_exposed_cum_sd
input$x_raw_or_percent <- "percent" # raw percent
input$choice_combos_choice_curve <- c("Long horizon, free choice 1", "Short horizon, free choice 1") # "Short horizon, free choice 1" "Long horizon, free choice 1"  "Long horizon, free choice 2"  "Long horizon, free choice 3"  "Long horizon, free choice 4"  "Long horizon, free choice 5"
input$x_comparison_group <- "mult" # rew_exposed_cum_sd rew_exposed_cum_mean rew_latent side rand
input$x_comparison_dimension <- "rt" # rew_exposed_cum_mean rew_latent difficulty rand rew_exposed_cum_sd
input$show_CI_choice_curve <- T # F

choice_and_learning_plots("choice_curve")

Difficulty is measured here by scaled baseline self-rated difficulty

input$batch_choice_curve <- "replication"   # "exploratory" "replication"
input$y_var_choice_curve <- "mult" # accuracy bigger_rand bigger_side bigger_rew_exposed_cum_mean bigger_rew_exposed_cum_count bigger_rew_latent bigger_rew_exposed_cum_sd
input$x_raw_or_percent <- "percent" # raw percent
input$choice_combos_choice_curve <- c("Long horizon, free choice 1", "Short horizon, free choice 1") # "Short horizon, free choice 1" "Long horizon, free choice 1"  "Long horizon, free choice 2"  "Long horizon, free choice 3"  "Long horizon, free choice 4"  "Long horizon, free choice 5"
input$x_comparison_group <- "mult" # rew_exposed_cum_sd rew_exposed_cum_mean rew_latent side rand
input$x_comparison_dimension <- "difficulty" # rew_exposed_cum_mean rew_latent difficulty rand rew_exposed_cum_sd
input$show_CI_choice_curve <- T # F

choice_and_learning_plots("choice_curve")

Probability of choosing mult based on how much more or less rewarding (in points) it’s been, compared to addition side

input$batch_choice_curve <- "replication"   # "exploratory" "replication"
input$y_var_choice_curve <- "mult" # mult accuracy bigger_rand bigger_side bigger_rew_exposed_cum_mean bigger_rew_exposed_cum_count bigger_rew_latent bigger_rew_exposed_cum_sd
input$x_raw_or_percent <- "raw" # raw percent
input$choice_combos_choice_curve <- c("Long horizon, free choice 1", "Short horizon, free choice 1") # "Short horizon, free choice 1" "Long horizon, free choice 1"  "Long horizon, free choice 2"  "Long horizon, free choice 3"  "Long horizon, free choice 4"  "Long horizon, free choice 5"
input$x_comparison_group <- "mult" # mult rew_exposed_cum_sd rew_exposed_cum_mean rew_latent side rand
input$x_comparison_dimension <- "rew_exposed_cum_mean" # rt rew_exposed_cum_mean rew_latent difficulty rand rew_exposed_cum_sd
input$show_CI_choice_curve <- T # T F
choice_and_learning_plots("choice_curve")

Choice Curves (for exploratory data)

How much harder mult is than add side and likelihood of choosing mult

Difficulty is measured here by raw baseline RT

input <- list()

input$batch_choice_curve <- "exploratory"   # "exploratory" "replication"
input$y_var_choice_curve <- "mult" # accuracy bigger_rand bigger_side bigger_rew_exposed_cum_mean bigger_rew_exposed_cum_count bigger_rew_latent bigger_rew_exposed_cum_sd
input$x_raw_or_percent <- "raw" # raw percent
input$choice_combos_choice_curve <- c("Long horizon, free choice 1", "Short horizon, free choice 1") # "Short horizon, free choice 1" "Long horizon, free choice 1"  "Long horizon, free choice 2"  "Long horizon, free choice 3"  "Long horizon, free choice 4"  "Long horizon, free choice 5"
input$x_comparison_group <- "mult" # rew_exposed_cum_sd rew_exposed_cum_mean rew_latent side rand
input$x_comparison_dimension <- "rt" # rew_exposed_cum_mean rew_latent difficulty rand rew_exposed_cum_sd
input$show_CI_choice_curve <- T # F

choice_and_learning_plots("choice_curve")

Difficulty is measured here by raw baseline self-rated difficulty

input$batch_choice_curve <- "exploratory"   # "exploratory" "replication"
input$y_var_choice_curve <- "mult" # accuracy bigger_rand bigger_side bigger_rew_exposed_cum_mean bigger_rew_exposed_cum_count bigger_rew_latent bigger_rew_exposed_cum_sd
input$x_raw_or_percent <- "raw" # raw percent
input$choice_combos_choice_curve <- c("Long horizon, free choice 1", "Short horizon, free choice 1") # "Short horizon, free choice 1" "Long horizon, free choice 1"  "Long horizon, free choice 2"  "Long horizon, free choice 3"  "Long horizon, free choice 4"  "Long horizon, free choice 5"
input$x_comparison_group <- "mult" # rew_exposed_cum_sd rew_exposed_cum_mean rew_latent side rand
input$x_comparison_dimension <- "difficulty" # rew_exposed_cum_mean rew_latent difficulty rand rew_exposed_cum_sd
input$show_CI_choice_curve <- T # F

choice_and_learning_plots("choice_curve")

Next two plots are same as previous two, except difficulty has been scaled between 1-100 rather than being in raw units

Difficulty is measured here by scaled baseline RT

input$batch_choice_curve <- "exploratory"   # "exploratory" "replication"
input$y_var_choice_curve <- "mult" # accuracy bigger_rand bigger_side bigger_rew_exposed_cum_mean bigger_rew_exposed_cum_count bigger_rew_latent bigger_rew_exposed_cum_sd
input$x_raw_or_percent <- "percent" # raw percent
input$choice_combos_choice_curve <- c("Long horizon, free choice 1", "Short horizon, free choice 1") # "Short horizon, free choice 1" "Long horizon, free choice 1"  "Long horizon, free choice 2"  "Long horizon, free choice 3"  "Long horizon, free choice 4"  "Long horizon, free choice 5"
input$x_comparison_group <- "mult" # rew_exposed_cum_sd rew_exposed_cum_mean rew_latent side rand
input$x_comparison_dimension <- "rt" # rew_exposed_cum_mean rew_latent difficulty rand rew_exposed_cum_sd
input$show_CI_choice_curve <- T # F

choice_and_learning_plots("choice_curve")

Difficulty is measured here by scaled baseline self-rated difficulty

input$batch_choice_curve <- "exploratory"   # "exploratory" "replication"
input$y_var_choice_curve <- "mult" # accuracy bigger_rand bigger_side bigger_rew_exposed_cum_mean bigger_rew_exposed_cum_count bigger_rew_latent bigger_rew_exposed_cum_sd
input$x_raw_or_percent <- "percent" # raw percent
input$choice_combos_choice_curve <- c("Long horizon, free choice 1", "Short horizon, free choice 1") # "Short horizon, free choice 1" "Long horizon, free choice 1"  "Long horizon, free choice 2"  "Long horizon, free choice 3"  "Long horizon, free choice 4"  "Long horizon, free choice 5"
input$x_comparison_group <- "mult" # rew_exposed_cum_sd rew_exposed_cum_mean rew_latent side rand
input$x_comparison_dimension <- "difficulty" # rew_exposed_cum_mean rew_latent difficulty rand rew_exposed_cum_sd
input$show_CI_choice_curve <- T # F

choice_and_learning_plots("choice_curve")

Probability of choosing mult based on how much more or less rewarding (in points) it’s been, compared to addition side

input$batch_choice_curve <- "exploratory"   # "exploratory" "replication"
input$y_var_choice_curve <- "mult" # mult accuracy bigger_rand bigger_side bigger_rew_exposed_cum_mean bigger_rew_exposed_cum_count bigger_rew_latent bigger_rew_exposed_cum_sd
input$x_raw_or_percent <- "raw" # raw percent
input$choice_combos_choice_curve <- c("Long horizon, free choice 1", "Short horizon, free choice 1") # "Short horizon, free choice 1" "Long horizon, free choice 1"  "Long horizon, free choice 2"  "Long horizon, free choice 3"  "Long horizon, free choice 4"  "Long horizon, free choice 5"
input$x_comparison_group <- "mult" # mult rew_exposed_cum_sd rew_exposed_cum_mean rew_latent side rand
input$x_comparison_dimension <- "rew_exposed_cum_mean" # rt rew_exposed_cum_mean rew_latent difficulty rand rew_exposed_cum_sd
input$show_CI_choice_curve <- T # T F
choice_and_learning_plots("choice_curve")

LS0tCnRpdGxlOiAiT3Bwb3J0dW5pc3RpYyBFeHBsb3JhdGlvbiDigJQgUmVwbGljYXRpb24gRGF0YSIKZGF0ZTogIkxhc3QgdXBkYXRlZDogYHIgZm9ybWF0KFN5cy50aW1lKCksICclZCAlQiwgJVknKWAiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgICB0aGVtZTogdW5pdGVkCiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDoKICAgICAgY29sbGFwc2VkOiBmYWxzZQogICAgICBzbW9vdGhfc2Nyb2xsOiB0cnVlCiAgICB0b2NfZGVwdGg6IDMKICAgIG51bWJlcl9zZWN0aW9uczogZmFsc2UKICAgIGNvZGVfZm9sZGluZzogaGlkZQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQotLS0KCmBgYHtjc3MsIGVjaG89RkFMU0V9CmJvZHkgewogIGZvbnQtc2l6ZTogMS42cmVtOwogIHRleHQtYWxpZ246IGp1c3RpZnk7Cn0KCi50aXRsZSB7CiAgZm9udC1zaXplOiA0N3B4OwogIGNvbG9yOiBmaXJlYnJpY2s7Cn0KCmgxLGgyLGgzLGg0LGg1IHsKICB0ZXh0LWFsaWduOiBsZWZ0Owp9CmBgYAoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldChtZXNzYWdlID0gRkFMU0UpCgpyZXJ1bl9maXRfbW9kZWxzIDw8LSAibm8iCgpzb3VyY2UoaGVyZTo6aGVyZSgiQW5hbHlzaXMiLCAibWFpbl90YXNrIiwgInBhY2thZ2VzLlIiKSkKbGlicmFyeShwYXRjaHdvcmspCnNvdXJjZShoZXJlOjpoZXJlKCJBbmFseXNpcyIsICJtYWluX3Rhc2siLCAiZml0LlIiKSkKc291cmNlKGhlcmU6OmhlcmUoIkFuYWx5c2lzIiwgIm1haW5fdGFzayIsICJwbG90dGluZ19mdW5jcy5SIikpCgoKIyBmaXJzdCwgbGV0J3MgY29tcGlsZSBhIGRmIG9mIHRoZSBwYXJ0aWNpcGFudHMgd2hvc2UgZGF0YSBwYXNzZXMKIyBvdXIgZXhjbHVzaW9uIGNyaXRlcmlhOyBub3RlIHRoYXQgdW5saWtlIHRoZSBgZnJlZV9jaG9pY2VzLmNzdmAgZmlsZSwKIyB3aGljaCBhbHNvIHBydW5lcyBwYXJ0aWNpcGFudHMgd2hvIGZhaWwgdG8gbWVldCB0aGUgZXhjbHVzaW9uCiMgY3JpdGVyaWEsIHRoaXMgZGYga2VlcHMgZm9yY2VkIGNob2ljZXMsIHRvbzsga2VlcGluZyB0aGVzZSBmb3JjZWQgY2hvaWNlCiMgdHJpYWxzIHdpbGwgYmUgdXNlZnVsIGZvciBhbmFseXppbmcgd2hldGhlciBwYXJ0aWNpcGFudHMgdG9vayBtYXNzaXZlIGJyZWFrcwojIGJldHdlZW4gYW55IHRyaWFscwoKcHJlcHJvY2Vzc2VkX2RmIDwtIHJlYWRfcGFycXVldChoZXJlKCJEYXRhIiwgIk1haW5fVGFzayIsICJwcmVwcm9jZXNzZWRfZGYucGFycXVldCIpKQpmcmVlX2Nob2ljZV9kZiA8PC0gcmVhZF9jc3YoaGVyZSgiRGF0YSIsICJNYWluX1Rhc2siLCAiZnJlZV9jaG9pY2VzLmNzdiIpKQoKc3ViaWRzX3dpdGhfZW5vdWdoX3RyaWFscyA8LSBwcmVwcm9jZXNzZWRfZGYgJT4lCiAgZ3JvdXBfYnkoYmF0Y2gpICU+JQogIGNvdW50KHN1YmlkKSAlPiUKICBzbGljZV9tYXgobikgJT4lCiAgcHVsbChzdWJpZCkKCgpwcmVwcm9jZXNzZWRfZGZfdXNhYmxlX3BhcnRpY2lwYW50c19mdWxsX2RhdGFfc2V0IDwtIHByZXByb2Nlc3NlZF9kZiAlPiUKICBmaWx0ZXIoCiAgICBzdWJpZCAlaW4lIHN1Ymlkc193aXRoX2Vub3VnaF90cmlhbHMsCiAgICBxMSA9PSAiTm90IGF0IGFsbCIsCiAgICBxMiA9PSAiTm90IGF0IGFsbCIsCiAgICBxMyA9PSAiQWx3YXlzIiwKICAgIHN1Yl9hdmdfYWNjdXJhY3kgPiAuOAogICkKCnBhcnRpY2lwYW50c19ieV9leHBlcmltZW50X2R1cmF0aW9uIDwtCiAgcHJlcHJvY2Vzc2VkX2RmX3VzYWJsZV9wYXJ0aWNpcGFudHNfZnVsbF9kYXRhX3NldCAlPiUgCiAgZmlsdGVyKGZvcmNlZF9jaG9pY2UgPT0gMCkgJT4lCiAgZ3JvdXBfYnkoc3ViaWQsIGJhdGNoKSAlPiUKICBzdW1tYXJpc2UoCiAgICBtYXhfdGltZV9lbGFwc2VkID0gbWF4KHRpbWVfZWxhcHNlZF9tYWluX2V4cCkgLyA2MDAwMCwKICAgIG1lZGlhbl9jaG9pY2VfdGltZSA9IG1lZGlhbihjaG9pY2VfdGltZSkgLyAxMDAwCiAgKQoKdHJpYWxzX2ZvbGxvd2luZ19tYXNzaXZlX2RlbGF5cyA8LSAKcHJlcHJvY2Vzc2VkX2RmICU+JQogICAgZmlsdGVyKAogICAgICAgIHN1YmlkICVpbiUgc3ViaWRzX3dpdGhfZW5vdWdoX3RyaWFscywKICAgICAgICBxMSA9PSAiTm90IGF0IGFsbCIsCiAgICAgICAgcTIgPT0gIk5vdCBhdCBhbGwiLAogICAgICAgIHEzID09ICJBbHdheXMiLAogICAgICAgIHN1Yl9hdmdfYWNjdXJhY3kgPiAuOAogICAgKSAlPiUKICAgIGdyb3VwX2J5KHN1YmlkLCBmb3JjZWRfY2hvaWNlKSAlPiUKICAgIG11dGF0ZShwZXJjX211bHQgPSBpZl9lbHNlKGZvcmNlZF9jaG9pY2UgPT0gMSwgTkFfcmVhbF8sIG1lYW4oc2VsZWN0aW9uID09ICJtdWx0IikpKSAlPiUKICAgIGdyb3VwX2J5KHN1YmlkKSAlPiUKICAgIG11dGF0ZShwZXJjX211bHQgPSBtZWFuKHBlcmNfbXVsdCwgbmEucm0gPSBUKSkgJT4lCiAgICBmaWx0ZXIoCiAgICAgICAgYmV0d2VlbihwZXJjX211bHQsIC4xNSwgLjg1KQogICAgKSAlPiUKICAgIHVuZ3JvdXAoKSAlPiUKICAgIG11dGF0ZShjaG9pY2VfdGltZSA9IGNob2ljZV90aW1lIC8gKDYwICogMTAwMCkpICU+JQogICAgZmlsdGVyKGNob2ljZV90aW1lID4gMjApICU+JQogICAgc2VsZWN0KHN1YmlkLCBnYW1lX25yLCB0cmlhbF9uciwgYmF0Y2gsIGNob2ljZV90aW1lKSAlPiUKICAgIGFycmFuZ2Uoc3ViaWQsIGNob2ljZV90aW1lKQoKcGNwdHNfdGFraW5nX21hc3NpdmVfZGVsYXlzIDwtIHRyaWFsc19mb2xsb3dpbmdfbWFzc2l2ZV9kZWxheXMgJT4lCiAgcHVsbChzdWJpZCkgJT4lCiAgdW5pcXVlCgpjdXN0b21fY29tcGFyZV9wYWlyZWRfZml0cyA8LSBmdW5jdGlvbihwYWlyX2NvbXBhaXJpc29uLCBjb2VmX29mX2ludGVyZXN0LCBrZWVwX2JhdGNoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtlZXBfc2VwYXJhdGVfYnlfZXhwb3N1cmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2VlcF9pdiwga2VlcF9hZ2dyZWdhdGlvbiwga2VlcF9jb250aW51dW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXBfMSwgZ3JvdXBfMiwgZ3JvdXBfMV9leHBvc3VyZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91cF8yX2V4cG9zdXJlLCBtaW5fZHVyYXRpb24sIG1heF9kdXJhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlX29mX3Rlc3QsIHJ1bl90ZXN0ID0gVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwY3B0c190b19leGNsdWRlID0gYygpKXsKICAKICBwYWlyZWRfZml0cyA8LSBsb2FkX3BhaXJlZF9maXRzKAogICAga2VlcF9iYXRjaCwga2VlcF9zZXBhcmF0ZV9ieV9leHBvc3VyZSwga2VlcF9pdiwKICAgIGtlZXBfYWdncmVnYXRpb24sIGtlZXBfY29udGludXVtLCBncm91cF8xLCBncm91cF8yLCBncm91cF8xX2V4cG9zdXJlLAogICAgZ3JvdXBfMl9leHBvc3VyZQogICkgJT4lCiAgICBmaWx0ZXIoIXN1YmlkICVpbiUgcGNwdHNfdG9fZXhjbHVkZSkgJT4lCiAgICBhcnJhbmdlKHN1YmlkLCBmcmVlX2Nob2ljZV9sYWJlbCkgJT4lCiAgICBsZWZ0X2pvaW4ocGFydGljaXBhbnRzX2J5X2V4cGVyaW1lbnRfZHVyYXRpb24pICU+JQogICAgZmlsdGVyKG1heF90aW1lX2VsYXBzZWQgPj0gbWluX2R1cmF0aW9uLCBtYXhfdGltZV9lbGFwc2VkIDw9IG1heF9kdXJhdGlvbikKICAKICBuX3BhcnRpY2lwYW50cyA8LSBuX2Rpc3RpbmN0KHBhaXJlZF9maXRzJHN1YmlkKQogIAogIGlmIChydW5fdGVzdCl7CiAgICBleGVjKAogICAgICB0eXBlX29mX3Rlc3QsCiAgICAgIHBhaXJlZF9maXRzICU+JQogICAgICAgIGZpbHRlcihmcmVlX2Nob2ljZV9sYWJlbCA9PSBncm91cF8xKSAlPiUKICAgICAgICBwdWxsKCEhY29lZl9vZl9pbnRlcmVzdCksCiAgICAgIHBhaXJlZF9maXRzICU+JQogICAgICAgIGZpbHRlcihmcmVlX2Nob2ljZV9sYWJlbCA9PSBncm91cF8yKSAlPiUKICAgICAgICBwdWxsKCEhY29lZl9vZl9pbnRlcmVzdCksCiAgICAgIHBhaXJlZCA9IFQsCiAgICAgIGFsdGVybmF0aXZlID0gcGFpcl9jb21wYWlyaXNvbgogICAgKSAlPiUKICAgICAgYnJvb206OnRpZHkoKSAlPiUKICAgICAgbXV0YXRlKG51bV9wYXJ0aWNpcGFudHMgPSBuX3BhcnRpY2lwYW50cykKICB9IGVsc2V7CiAgICBwaXZvdF93aWRlcigKICAgICAgcGFpcmVkX2ZpdHMsCiAgICAgIGlkID0gYygKICAgICAgICBiYXRjaCwgc3ViaWQsIGZyZWVfY2hvaWNlX3RyaWFsLCBlcXVhbF9leHBvc3VyZSwgc2VwYXJhdGVfYnlfZXhwb3N1cmUsCiAgICAgICAgaXYsIGFnZ3JlZ2F0aW9uLCBjb250aW51dW0sIG1heF90aW1lX2VsYXBzZWQsIG1lZGlhbl9jaG9pY2VfdGltZQogICAgICApLAogICAgICBuYW1lc19mcm9tID0gaG9yaXpvbl90eXBlLAogICAgICB2YWx1ZXNfZnJvbSA9IGMoCiAgICAgICAgaG9yaXpvbiwgZnJlZV9jaG9pY2VfbGFiZWwsIHRvdGFsX211bHRfY2hvc2VuLCB0b3RhbF90cmlhbHMsIGRhdGEsIAogICAgICAgIHRlbXBfY29lZiwgZGlmZmljdWx0eV9jb2VmLCBzaWRlX2NvZWYsIGluZm9ybWF0aW9uX2NvZWYKICAgICAgKQogICAgKQogIH0KCn0KCmBgYAoKIyMjIFRoZSBtb2RlbCB3ZSBhcmUgdXNpbmcgdG8gZml0IHRoZSBkYXRhCgoKJCQKcF97bXVsdH0gPSBcZnJhY3sxfXsxICsgZXhwKFxmcmFje1Jfe211bHR9IC0gUl97YWRkfSArIFxhbHBoYShJX3ttdWx0fSAtIElfe2FkZH0pICsgRChNX3thZGR9IC0gTV97bXVsdH0pICsgQn17XHNxcnQyXHNpZ21hfSl9CiQkCgojIyMgQXJlIHRoZSBjb2VmZmljaWVudHMgc2lnbmlmaWNhbnRseSBkaWZmZXJlbnQgYmV0d2VlbiB0aGUgc2hvcnQgYW5kIGxvbmcgaG9yaXpvbnM/CmBgYHtyIG1haW5fdGVzdF9vZl9jb2VmZmljaWVudHN9CgptYXAyX2RmcigKICBjKCJncmVhdGVyIiwgImxlc3MiLCAibGVzcyIpLAogIGMoImRpZmZpY3VsdHkiLCAiaW5mb3JtYXRpb24iLCAidGVtcCIpLAogIH5jdXN0b21fY29tcGFyZV9wYWlyZWRfZml0cygKICAueCwgcGFzdGUwKC55LCAiX2NvZWYiKSwgInJlcGxpY2F0aW9uIiwgRiwgInJ0IiwgInBlcmNlbnRpbGUiLAogICJjb250aW51b3VzIiwgIlNob3J0IGhvcml6b24sIGZyZWUgY2hvaWNlIDEiLCAiTG9uZyBob3Jpem9uLCBmcmVlIGNob2ljZSAxIiwKICBGLCBGLCAwLCBJbmYsICJ0LnRlc3QiCiAgKSAlPiUKICAgIG11dGF0ZShjb2VmZmljaWVudCA9IC55KSAlPiUKICAgIHNlbGVjdChjb2VmZmljaWVudCwgZXN0aW1hdGUsIHN0YXRpc3RpYywgcC52YWx1ZSkKKQoKYGBgCgojIyMgQ29lZmZpY2llbnQgZXN0aW1hdGVzIGZvciBsb25nIHZzLiBzaG9ydCBob3Jpem9ucyBmb3IgZXhwbG9yYXRvcnkgYW5kIHJlcGxpY2F0aW9uIGRhdGEKCmBgYHtyIHZpc3VhbGl6ZSBjb2VmZmljaWVudHMsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD0xNX0KCgptYXAoCiAgYygiZGlmZmljdWx0eSIsICJpbmZvcm1hdGlvbiIsICJ0ZW1wIiksCiAgfnsKICAgIAogICAgbXlfYWdncmVnYXRpb24gPSAicGVyY2VudGlsZSIKICAgIG15X2NvZWYgPSBwYXN0ZTAoLngsICJfY29lZiIpCiAgICBteV9pdiA9ICJydCIKCmV4cGxvcmF0b3J5X3Nob3J0IDwtIGhlcmUoIkFuYWx5c2lzIiwgIm1haW5fdGFzayIsICJmaXRzLnJkcyIpICU+JQogIHJlYWRfcmRzKCkgJT4lCiAgZmlsdGVyKAogICAgYmF0Y2ggPT0gImV4cGxvcmF0b3J5IiwKICAgIHNlcGFyYXRlX2J5X2V4cG9zdXJlID09IEYsCiAgICBpdiA9PSBteV9pdiwKICAgIGFnZ3JlZ2F0aW9uID09IG15X2FnZ3JlZ2F0aW9uLAogICAgY29udGludXVtID09ICJjb250aW51b3VzIiwKICAgIChmcmVlX2Nob2ljZV9sYWJlbCA9PSAiU2hvcnQgaG9yaXpvbiwgZnJlZSBjaG9pY2UgMSIgJiBlcXVhbF9leHBvc3VyZSA9PSBGKSB8CiAgICAgIChmcmVlX2Nob2ljZV9sYWJlbCA9PSAiTG9uZyBob3Jpem9uLCBmcmVlIGNob2ljZSAxIiAmIGVxdWFsX2V4cG9zdXJlID09IEYpCiAgKSAlPiUKICBncm91cF9ieShzdWJpZCkgJT4lCiAgZmlsdGVyKAogICAgbWluKHRvdGFsX211bHRfY2hvc2VuKSA+PSAzLAogICAgbWF4KHRvdGFsX3RyaWFscyAtIHRvdGFsX211bHRfY2hvc2VuKSA+PSAzCiAgKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgbXV0YXRlKGFjcm9zcyhjKGZyZWVfY2hvaWNlX3RyaWFsKSwgYXNfZmFjdG9yKSkgJT4lCiAgYXJyYW5nZShzdWJpZCwgZnJlZV9jaG9pY2VfbGFiZWwpICU+JQogIGZpbHRlcihmcmVlX2Nob2ljZV9sYWJlbCA9PSAiU2hvcnQgaG9yaXpvbiwgZnJlZSBjaG9pY2UgMSIpICU+JQogIHB1bGwoISFteV9jb2VmKQoKZXhwbG9yYXRvcnlfbG9uZyA8LSBoZXJlKCJBbmFseXNpcyIsICJtYWluX3Rhc2siLCAiZml0cy5yZHMiKSAlPiUKICByZWFkX3JkcygpICU+JQogIGZpbHRlcigKICAgIGJhdGNoID09ICJleHBsb3JhdG9yeSIsCiAgICBzZXBhcmF0ZV9ieV9leHBvc3VyZSA9PSBGLAogICAgaXYgPT0gbXlfaXYsCiAgICBhZ2dyZWdhdGlvbiA9PSBteV9hZ2dyZWdhdGlvbiwKICAgIGNvbnRpbnV1bSA9PSAiY29udGludW91cyIsCiAgICAoZnJlZV9jaG9pY2VfbGFiZWwgPT0gIlNob3J0IGhvcml6b24sIGZyZWUgY2hvaWNlIDEiICYgZXF1YWxfZXhwb3N1cmUgPT0gRikgfAogICAgICAoZnJlZV9jaG9pY2VfbGFiZWwgPT0gIkxvbmcgaG9yaXpvbiwgZnJlZSBjaG9pY2UgMSIgJiBlcXVhbF9leHBvc3VyZSA9PSBGKQogICkgJT4lCiAgZ3JvdXBfYnkoc3ViaWQpICU+JQogIGZpbHRlcigKICAgIG1pbih0b3RhbF9tdWx0X2Nob3NlbikgPj0gMywKICAgIG1heCh0b3RhbF90cmlhbHMgLSB0b3RhbF9tdWx0X2Nob3NlbikgPj0gMwogICkgJT4lCiAgdW5ncm91cCgpICU+JQogIG11dGF0ZShhY3Jvc3MoYyhmcmVlX2Nob2ljZV90cmlhbCksIGFzX2ZhY3RvcikpICU+JQogIGFycmFuZ2Uoc3ViaWQsIGZyZWVfY2hvaWNlX2xhYmVsKSAlPiUKICBmaWx0ZXIoZnJlZV9jaG9pY2VfbGFiZWwgPT0gIkxvbmcgaG9yaXpvbiwgZnJlZSBjaG9pY2UgMSIpICU+JQogIHB1bGwoISFteV9jb2VmKQoKcmVwbGljYXRpb25fc2hvcnQgPC0gaGVyZSgiQW5hbHlzaXMiLCAibWFpbl90YXNrIiwgImZpdHMucmRzIikgJT4lCiAgcmVhZF9yZHMoKSAlPiUKICBmaWx0ZXIoCiAgICBiYXRjaCA9PSAicmVwbGljYXRpb24iLAogICAgc2VwYXJhdGVfYnlfZXhwb3N1cmUgPT0gRiwKICAgIGl2ID09IG15X2l2LAogICAgYWdncmVnYXRpb24gPT0gbXlfYWdncmVnYXRpb24sCiAgICBjb250aW51dW0gPT0gImNvbnRpbnVvdXMiLAogICAgKGZyZWVfY2hvaWNlX2xhYmVsID09ICJTaG9ydCBob3Jpem9uLCBmcmVlIGNob2ljZSAxIiAmIGVxdWFsX2V4cG9zdXJlID09IEYpIHwKICAgICAgKGZyZWVfY2hvaWNlX2xhYmVsID09ICJMb25nIGhvcml6b24sIGZyZWUgY2hvaWNlIDEiICYgZXF1YWxfZXhwb3N1cmUgPT0gRikKICApICU+JQogIGdyb3VwX2J5KHN1YmlkKSAlPiUKICBmaWx0ZXIoCiAgICBtaW4odG90YWxfbXVsdF9jaG9zZW4pID49IDMsCiAgICBtYXgodG90YWxfdHJpYWxzIC0gdG90YWxfbXVsdF9jaG9zZW4pID49IDMKICApICU+JQogIHVuZ3JvdXAoKSAlPiUKICBtdXRhdGUoYWNyb3NzKGMoZnJlZV9jaG9pY2VfdHJpYWwpLCBhc19mYWN0b3IpKSAlPiUKICBhcnJhbmdlKHN1YmlkLCBmcmVlX2Nob2ljZV9sYWJlbCkgJT4lCiAgZmlsdGVyKGZyZWVfY2hvaWNlX2xhYmVsID09ICJTaG9ydCBob3Jpem9uLCBmcmVlIGNob2ljZSAxIikgJT4lCiAgcHVsbCghIW15X2NvZWYpCgoKcmVwbGljYXRpb25fbG9uZyA8LSBoZXJlKCJBbmFseXNpcyIsICJtYWluX3Rhc2siLCAiZml0cy5yZHMiKSAlPiUKICByZWFkX3JkcygpICU+JQogIGZpbHRlcigKICAgIGJhdGNoID09ICJyZXBsaWNhdGlvbiIsCiAgICBzZXBhcmF0ZV9ieV9leHBvc3VyZSA9PSBGLAogICAgaXYgPT0gbXlfaXYsCiAgICBhZ2dyZWdhdGlvbiA9PSBteV9hZ2dyZWdhdGlvbiwKICAgIGNvbnRpbnV1bSA9PSAiY29udGludW91cyIsCiAgICAoZnJlZV9jaG9pY2VfbGFiZWwgPT0gIlNob3J0IGhvcml6b24sIGZyZWUgY2hvaWNlIDEiICYgZXF1YWxfZXhwb3N1cmUgPT0gRikgfAogICAgICAoZnJlZV9jaG9pY2VfbGFiZWwgPT0gIkxvbmcgaG9yaXpvbiwgZnJlZSBjaG9pY2UgMSIgJiBlcXVhbF9leHBvc3VyZSA9PSBGKQogICkgJT4lCiAgZ3JvdXBfYnkoc3ViaWQpICU+JQogIGZpbHRlcigKICAgIG1pbih0b3RhbF9tdWx0X2Nob3NlbikgPj0gMywKICAgIG1heCh0b3RhbF90cmlhbHMgLSB0b3RhbF9tdWx0X2Nob3NlbikgPj0gMwogICkgJT4lCiAgdW5ncm91cCgpICU+JQogIG11dGF0ZShhY3Jvc3MoYyhmcmVlX2Nob2ljZV90cmlhbCksIGFzX2ZhY3RvcikpICU+JQogIGFycmFuZ2Uoc3ViaWQsIGZyZWVfY2hvaWNlX2xhYmVsKSAlPiUKICBmaWx0ZXIoZnJlZV9jaG9pY2VfbGFiZWwgPT0gIkxvbmcgaG9yaXpvbiwgZnJlZSBjaG9pY2UgMSIpICU+JQogIHB1bGwoISFteV9jb2VmKQoKCmJpbmRfcm93cygKICB0aWJibGUoCiAgICB4ID0gImV4cGxvcmF0b3J5X3Nob3J0IiwKICAgIHkgPSBleHBsb3JhdG9yeV9zaG9ydAogICksCiAgCiAgdGliYmxlKAogICAgeCA9ICJleHBsb3JhdG9yeV9sb25nIiwKICAgIHkgPSBleHBsb3JhdG9yeV9sb25nCiAgKSwKICAKICB0aWJibGUoCiAgICB4ID0gInJlcGxpY2F0aW9uX3Nob3J0IiwKICAgIHkgPSByZXBsaWNhdGlvbl9zaG9ydAogICksCiAgCiAgdGliYmxlKAogICAgeCA9ICJyZXBsaWNhdGlvbl9sb25nIiwKICAgIHkgPSByZXBsaWNhdGlvbl9sb25nCiAgKQopICU+JQogIGdncGxvdChhZXMoeCA9IHgsIHkgPSB5KSkgKwogIGdlb21fdmlvbGluKCkgKwogIGdlb21faml0dGVyKHdpZHRoID0uMSkgKwogIGdlb21fYm94cGxvdCh3aWR0aCA9IC4xLCBvdXRsaWVyLnNoYXBlID0gTkEpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsKICBsYWJzKAogICAgdGl0bGUgPSAueCwKICAgIHggPSAiIiwKICAgIHkgPSAiQ29lZmZpY2VudCBFc3RpbWF0ZSBwZXIgUGFydGljaXBhbnQiCiAgKQogIH0KKSAlPiUKICByZWR1Y2UoYC9gKQoKCmBgYAoKCgpgYGB7ciwgYW5hbHlzaXNfY29tYm9zX2RmLCByb3dzLnByaW50PTUwfQoKYW5hbHlzaXNfY29tYm9zIDwtIGV4cGFuZC5ncmlkKAogIHBhaXJfY29tcGFpcmlzb24gPSBjKCJncmVhdGVyIiwgImxlc3MiKSwKICBjb2VmX29mX2ludGVyZXN0ID0gYygiZGlmZmljdWx0eV9jb2VmIiwgImluZm9ybWF0aW9uX2NvZWYiLCAidGVtcF9jb2VmIiksCiAga2VlcF9iYXRjaCA9IGMoImV4cGxvcmF0b3J5IiwgInJlcGxpY2F0aW9uIiksCiAga2VlcF9zZXBhcmF0ZV9ieV9leHBvc3VyZSA9IEYsCiAga2VlcF9pdiA9IGMoInJ0IiwgImRpZmZpY3VsdHkiKSwKICBrZWVwX2FnZ3JlZ2F0aW9uID0gYygicmF3IiwgInBlcmNlbnRpbGUiKSwKICBrZWVwX2NvbnRpbnV1bSA9ICJjb250aW51b3VzIiwKICBncm91cF8xID0gIlNob3J0IGhvcml6b24sIGZyZWUgY2hvaWNlIDEiLAogIGdyb3VwXzIgPSAiTG9uZyBob3Jpem9uLCBmcmVlIGNob2ljZSAxIiwKICBtaW5fZHVyYXRpb24gPSBjKDApLAogIG1heF9kdXJhdGlvbiA9IGMoSW5mKSwKICB0eXBlX29mX3Rlc3QgPSBjKCJ0LnRlc3QiLCAid2lsY294LnRlc3QiKQopICU+JQogIG11dGF0ZSgKICAgIGdyb3VwXzFfZXhwb3N1cmUgPSBrZWVwX3NlcGFyYXRlX2J5X2V4cG9zdXJlLAogICAgZ3JvdXBfMl9leHBvc3VyZSA9IGtlZXBfc2VwYXJhdGVfYnlfZXhwb3N1cmUKICApICU+JQogIGZpbHRlcihtYXhfZHVyYXRpb24gPiBtaW5fZHVyYXRpb24pICU+JQogIGZpbHRlcigKICAgIChjb2VmX29mX2ludGVyZXN0ID09ICJkaWZmaWN1bHR5X2NvZWYiICYgIHBhaXJfY29tcGFpcmlzb24gPT0gImdyZWF0ZXIiKSB8CiAgICAgIGNvZWZfb2ZfaW50ZXJlc3QgIT0gImRpZmZpY3VsdHlfY29lZiIgJiBwYWlyX2NvbXBhaXJpc29uID09ICJsZXNzIikgJT4lCiAgcmVsb2NhdGUodHlwZV9vZl90ZXN0LCAuYWZ0ZXIgPSBsYXN0X2NvbCgpKSAlPiUKICBtdXRhdGUoYWNyb3NzKHdoZXJlKGlzLmZhY3RvciksIGFzLmNoYXJhY3RlcikpCgptYXBfZGZyKDE6bnJvdyhhbmFseXNpc19jb21ib3MpLCB+ewogIGFyb3cgPC0gYW5hbHlzaXNfY29tYm9zICU+JSBmaWx0ZXIocm93X251bWJlcigpID09IC54KQogIAogIGJyb3cgPC0gY3VzdG9tX2NvbXBhcmVfcGFpcmVkX2ZpdHMoCiAgICBhcm93JHBhaXJfY29tcGFpcmlzb24sIGFyb3ckY29lZl9vZl9pbnRlcmVzdCwgYXJvdyRrZWVwX2JhdGNoLAogICAgYXJvdyRrZWVwX3NlcGFyYXRlX2J5X2V4cG9zdXJlLCBhcm93JGtlZXBfaXYsIGFyb3cka2VlcF9hZ2dyZWdhdGlvbiwKICAgIGFyb3cka2VlcF9jb250aW51dW0sIGFyb3ckZ3JvdXBfMSwgYXJvdyRncm91cF8yLCBhcm93JGdyb3VwXzFfZXhwb3N1cmUsCiAgICBhcm93JGdyb3VwXzJfZXhwb3N1cmUsIGFyb3ckbWluX2R1cmF0aW9uLCBhcm93JG1heF9kdXJhdGlvbiwKICAgIGFyb3ckdHlwZV9vZl90ZXN0CiAgKQogIAogIGJpbmRfY29scyhhcm93LCBicm93KQogIAp9KSAlPiUKICBhcnJhbmdlKGNvZWZfb2ZfaW50ZXJlc3QsIGtlZXBfYmF0Y2gsIC1wLnZhbHVlKSAlPiUKICBtdXRhdGUoYWNyb3NzKHAudmFsdWUsIH5pbnNpZ2h0Ojpmb3JtYXRfcCgueCkpKSAlPiUKICBzZWxlY3QoY29lZl9vZl9pbnRlcmVzdCwga2VlcF9iYXRjaCwgcC52YWx1ZSwga2VlcF9pdiwga2VlcF9hZ2dyZWdhdGlvbiwgdHlwZV9vZl90ZXN0KSAlPiUKICByZW5hbWVfd2l0aCh+c3RyX3JlcGxhY2VfYWxsKC54LCAia2VlcF8iLCAiICIpLCBzdGFydHNfd2l0aCgia2VlcF8iKSkKCmBgYAoKCiMjIE1heWJlIHdlIHNob3VsZCBiZSBtb3JlIHZpZ2lsYW50IG9mIGhvdyBsb25nIHRhc2tzIGFyZSB0YWtpbmcgcGFydGljaXBhbnRzPwoKIyMjIEl0IGRvZXNuJ3QgYXBwZWFyIHRoYXQgcGFydGljaXBhbnRzIHdobyBmaW5pc2ggdGhlIHRhc2sgcXVpY2tseSBhcmUgcGFydGljdWxhcmx5IGRyaXZpbmcgdGhlIG51bGwgcmVzdWx0cyAoaS5lLiwgdGhlaXIgY29lZmZpY2llbnQgaXNuJ3QgcGFydGljdWxhbHkgbGFyZ2UpLgpgYGB7ciwgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTE1fQoKbWFwKAogICAgYygibWF4X3RpbWVfZWxhcHNlZCIsICJtZWRpYW5fY2hvaWNlX3RpbWUiKSwKICAgIGZ1bmN0aW9uKGRlc2lyZWRfeF9heGlzKXsKICAgICAgICBtYXAoYygiZXhwbG9yYXRvcnkiLCAicmVwbGljYXRpb24iKSwgfgogICAgICAgICAgICAgICAgY3VzdG9tX2NvbXBhcmVfcGFpcmVkX2ZpdHMoCiAgICAgICAgICAgICAgICAgICAgImdyZWF0ZXIiLCAiZGlmZmljdWx0eV9jb2VmIiwgLngsIEYsICJydCIsICJwZXJjZW50aWxlIiwKICAgICAgICAgICAgICAgICAgICAiY29udGludW91cyIsICJTaG9ydCBob3Jpem9uLCBmcmVlIGNob2ljZSAxIiwgIkxvbmcgaG9yaXpvbiwgZnJlZSBjaG9pY2UgMSIsCiAgICAgICAgICAgICAgICAgICAgRiwgRiwgMCwgSW5mLCAidC50ZXN0IiwgRgogICAgICAgICAgICAgICAgKSAlPiUKICAgICAgICAgICAgICAgIG11dGF0ZShkaWZmaWN1bHR5X2NvZWZfZGlmZiA9IGRpZmZpY3VsdHlfY29lZl9Mb25nIC0gZGlmZmljdWx0eV9jb2VmX1Nob3J0KSAlPiUKICAgICAgICAgICAgICAgIGZpbHRlcihtYXhfdGltZV9lbGFwc2VkIDwgMTAwKSAlPiUKICAgICAgICAgICAgICAgIGdncGxvdChhZXMoISFzeW0oZGVzaXJlZF94X2F4aXMpLCBkaWZmaWN1bHR5X2NvZWZfZGlmZikpICsKICAgICAgICAgICAgICAgIGdlb21fc21vb3RoKCkgKwogICAgICAgICAgICAgICAgZ2VvbV9wb2ludCgpICsKICAgICAgICAgICAgICAgIGxhYnMoCiAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSBwYXN0ZSgKICAgICAgICAgICAgICAgICAgICAgICAgLngsCiAgICAgICAgICAgICAgICAgICAgICAgICJiYXRjaCwiLAogICAgICAgICAgICAgICAgICAgICAgICBpZmVsc2UoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXNpcmVkX3hfYXhpcyA9PSAibWF4X3RpbWVfZWxhcHNlZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZXhwZXJpbWVudCBkdXJhdGlvbiAoaW5jbHVkaW5nIGluc3RyYykiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgImF2ZXJhZ2UgZnJlZSBjaG9pY2UgUlQiCiAgICAgICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICAgICAgICAgKSwKICAgICAgICAgICAgICAgICAgICB4ID0gaWZlbHNlKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzaXJlZF94X2F4aXMgPT0gIm1heF90aW1lX2VsYXBzZWQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIk1pbnV0ZXMgdGFrZW4gdG8gZ28gdGhyb3VnaCBlbnRpcmUgdGFzayIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQXZlcmFnZSB0aW1lIHRvIG1ha2UgYSBmcmVlIGNob2ljZSAoaW4gc2Vjb25kcykiCiAgICAgICAgICAgICAgICAgICAgICAgICksCiAgICAgICAgICAgICAgICAgICAgeSA9ICJEaWZmaWN1bHR5IENvZWZmaWNpZW50IgogICAgICAgICAgICAgICAgKQogICAgICAgICkgJT4lCiAgICAgICAgICAgIHJlZHVjZShgL2ApCiAgICB9CikgJT4lIHJlZHVjZShgfGApCgoKYGBgCgoKIyMjIEF2ZXJhZ2UgYW1vdW50IG9mIHRpbWUgc3BlbnQgb24gYSBmcmVlIGNob2ljZSwgb3ZlciB0aGUgY291cnNlIG9mIHRoZSB0YXNrIChleGNsdWRpbmcgMzIgdHJpYWxzIHRoYXQgbGFzdGVkIGxvbmdlciB0aGFuIDIgbWludXRlcykKYGBge3IgdGFza19xdWlja25lc3Nfb3Zlcl9jb3Vyc2Vfb2ZfZXhwZXJpbWVudH0KCmZyZWVfY2hvaWNlX2RmICU+JQogIG11dGF0ZShjaG9pY2VfdGltZSA9IGNob2ljZV90aW1lIC8gKDYwICogMTAwMCkpICU+JQogIGZpbHRlcihjaG9pY2VfdGltZSA8IDIpICU+JQogIGdncGxvdChhZXMob3ZlcmFsbF90cmlhbCwgY2hvaWNlX3RpbWUpKSArCiAgZ2VvbV9zbW9vdGgoKQoKYGBgCgoKIyMjIFNvbWUgcGFydGljaXBhbnRzIHRvb2sgYSBtYXNzaXZlIGFtb3VudCBvZiB0aW1lIChicmVha3MpIHRvIGNvbXBsZXRlIHNvbWUgb2YgdGhlIHRyaWFscwpgYGB7ciBsb25nX2JyZWFrcywgcm93cy5wcmludD01MH0KCnRyaWFsc19mb2xsb3dpbmdfbWFzc2l2ZV9kZWxheXMKYGBgCgojIyMgQnV0IG1vZGVsaW5nIHRoZSByZXN1bHRzIHdpdGhvdXQgdGhlc2UgcGFydGljaXBhbnRzIGRvZXNuJ3QgbWFrZSBvdXIgcmVzdWx0cyBhbnkgbW9yZSBzaWduaWZpY2FudAoKYGBge3IgcmVzdWx0c19hcmVudF9iZXR0ZXJfaWZfd2VfZGlzY2FyZF9wYXJ0aWNpcGFudHNfd2hvX2JyZWFrfQoKY3VzdG9tX2NvbXBhcmVfcGFpcmVkX2ZpdHMoCiAgICAgICAgICAgICAgICAgICAgImdyZWF0ZXIiLCAiZGlmZmljdWx0eV9jb2VmIiwgInJlcGxpY2F0aW9uIiwgRiwgInJ0IiwgInBlcmNlbnRpbGUiLAogICAgICAgICAgICAgICAgICAgICJjb250aW51b3VzIiwgIlNob3J0IGhvcml6b24sIGZyZWUgY2hvaWNlIDEiLCAiTG9uZyBob3Jpem9uLCBmcmVlIGNob2ljZSAxIiwKICAgICAgICAgICAgICAgICAgICBGLCBGLCAwLCBJbmYsICJ0LnRlc3QiLCBULCBwY3B0c190YWtpbmdfbWFzc2l2ZV9kZWxheXMKICAgICAgICAgICAgICAgICkgJT4lCiAgcHVsbChwLnZhbHVlKQpgYGAKCiMjIyBIb3dldmVyLCBpZiB3ZSBrZWVwIHRoZSBkYXRhIGZyb20gYWxsIHBhcnRpY2lwYW50cyBhbmQgZmlsdGVyIGVhY2ggb2YgdGhlc2UgcGFydGljaXBhbnRzIGJ5IGhvdyBmYXIgYWxvbmcgdGhleSB3ZXJlIGluIHRoZSB0YXNrLCB0aGUgcmVwbGljYXRpb24gZGF0YSBsb29rIG1vcmUgcHJvbWlzaW5nCgpgYGB7ciBhZHNzYX0KCnRyaWJibGUoCiAgfiJGaXJzdF94X1RyaWFscyIsIH4iRXhwbG9yYXRvcnkiLCB+IlJlcGxpY2F0aW9uIiwKICAyMCwgICAgICAgICAgICAgICAgMC4wNTY3MSwgICAgICAgIDAuNDg0OSwKICA0MCwgICAgICAgICAgICAgICAgMS4wNTNlLTA1LCAgICAgIDAuMDAyMzUxLAogIDYwLCAgICAgICAgICAgICAgICAyLjAxOWUtMDUsICAgICAgMC4wMzkwNiwKICA4MCwgICAgICAgICAgICAgICAgMi43MjllLTA3LCAgICAgIDAuMDU1MDkKKQpgYGAKCiMjIENob2ljZSBDdXJ2ZXMgKGZvciByZXBsaWNhdGlvbiBkYXRhKQoKIyMjIEhvdyBtdWNoIGhhcmRlciBtdWx0IGlzIHRoYW4gYWRkIHNpZGUgYW5kIGxpa2VsaWhvb2Qgb2YgY2hvb3NpbmcgbXVsdAoKRGlmZmljdWx0eSBpcyBtZWFzdXJlZCBoZXJlIGJ5IHJhdyBiYXNlbGluZSBSVAoKYGBge3IgZmlnLndpZHRoPTEwfQoKaW5wdXQgPC0gbGlzdCgpCgppbnB1dCRiYXRjaF9jaG9pY2VfY3VydmUgPC0gInJlcGxpY2F0aW9uIiAgICMgImV4cGxvcmF0b3J5IiAicmVwbGljYXRpb24iCmlucHV0JHlfdmFyX2Nob2ljZV9jdXJ2ZSA8LSAibXVsdCIgIyBhY2N1cmFjeSBiaWdnZXJfcmFuZCBiaWdnZXJfc2lkZSBiaWdnZXJfcmV3X2V4cG9zZWRfY3VtX21lYW4gYmlnZ2VyX3Jld19leHBvc2VkX2N1bV9jb3VudCBiaWdnZXJfcmV3X2xhdGVudCBiaWdnZXJfcmV3X2V4cG9zZWRfY3VtX3NkCmlucHV0JHhfcmF3X29yX3BlcmNlbnQgPC0gInJhdyIgIyByYXcgcGVyY2VudAppbnB1dCRjaG9pY2VfY29tYm9zX2Nob2ljZV9jdXJ2ZSA8LSBjKCJMb25nIGhvcml6b24sIGZyZWUgY2hvaWNlIDEiLCAiU2hvcnQgaG9yaXpvbiwgZnJlZSBjaG9pY2UgMSIpICMgIlNob3J0IGhvcml6b24sIGZyZWUgY2hvaWNlIDEiICJMb25nIGhvcml6b24sIGZyZWUgY2hvaWNlIDEiICAiTG9uZyBob3Jpem9uLCBmcmVlIGNob2ljZSAyIiAgIkxvbmcgaG9yaXpvbiwgZnJlZSBjaG9pY2UgMyIgICJMb25nIGhvcml6b24sIGZyZWUgY2hvaWNlIDQiICAiTG9uZyBob3Jpem9uLCBmcmVlIGNob2ljZSA1IgppbnB1dCR4X2NvbXBhcmlzb25fZ3JvdXAgPC0gIm11bHQiICMgcmV3X2V4cG9zZWRfY3VtX3NkIHJld19leHBvc2VkX2N1bV9tZWFuIHJld19sYXRlbnQgc2lkZSByYW5kCmlucHV0JHhfY29tcGFyaXNvbl9kaW1lbnNpb24gPC0gInJ0IiAjIHJld19leHBvc2VkX2N1bV9tZWFuIHJld19sYXRlbnQgZGlmZmljdWx0eSByYW5kIHJld19leHBvc2VkX2N1bV9zZAppbnB1dCRzaG93X0NJX2Nob2ljZV9jdXJ2ZSA8LSBUICMgRgoKY2hvaWNlX2FuZF9sZWFybmluZ19wbG90cygiY2hvaWNlX2N1cnZlIikKYGBgCgpEaWZmaWN1bHR5IGlzIG1lYXN1cmVkIGhlcmUgYnkgcmF3IGJhc2VsaW5lIHNlbGYtcmF0ZWQgZGlmZmljdWx0eQoKYGBge3IgZmlnLndpZHRoPTEwfQoKaW5wdXQkYmF0Y2hfY2hvaWNlX2N1cnZlIDwtICJyZXBsaWNhdGlvbiIgICAjICJleHBsb3JhdG9yeSIgInJlcGxpY2F0aW9uIgppbnB1dCR5X3Zhcl9jaG9pY2VfY3VydmUgPC0gIm11bHQiICMgYWNjdXJhY3kgYmlnZ2VyX3JhbmQgYmlnZ2VyX3NpZGUgYmlnZ2VyX3Jld19leHBvc2VkX2N1bV9tZWFuIGJpZ2dlcl9yZXdfZXhwb3NlZF9jdW1fY291bnQgYmlnZ2VyX3Jld19sYXRlbnQgYmlnZ2VyX3Jld19leHBvc2VkX2N1bV9zZAppbnB1dCR4X3Jhd19vcl9wZXJjZW50IDwtICJyYXciICMgcmF3IHBlcmNlbnQKaW5wdXQkY2hvaWNlX2NvbWJvc19jaG9pY2VfY3VydmUgPC0gYygiTG9uZyBob3Jpem9uLCBmcmVlIGNob2ljZSAxIiwgIlNob3J0IGhvcml6b24sIGZyZWUgY2hvaWNlIDEiKSAjICJTaG9ydCBob3Jpem9uLCBmcmVlIGNob2ljZSAxIiAiTG9uZyBob3Jpem9uLCBmcmVlIGNob2ljZSAxIiAgIkxvbmcgaG9yaXpvbiwgZnJlZSBjaG9pY2UgMiIgICJMb25nIGhvcml6b24sIGZyZWUgY2hvaWNlIDMiICAiTG9uZyBob3Jpem9uLCBmcmVlIGNob2ljZSA0IiAgIkxvbmcgaG9yaXpvbiwgZnJlZSBjaG9pY2UgNSIKaW5wdXQkeF9jb21wYXJpc29uX2dyb3VwIDwtICJtdWx0IiAjIHJld19leHBvc2VkX2N1bV9zZCByZXdfZXhwb3NlZF9jdW1fbWVhbiByZXdfbGF0ZW50IHNpZGUgcmFuZAppbnB1dCR4X2NvbXBhcmlzb25fZGltZW5zaW9uIDwtICJkaWZmaWN1bHR5IiAjIHJld19leHBvc2VkX2N1bV9tZWFuIHJld19sYXRlbnQgZGlmZmljdWx0eSByYW5kIHJld19leHBvc2VkX2N1bV9zZAppbnB1dCRzaG93X0NJX2Nob2ljZV9jdXJ2ZSA8LSBUICMgRgoKY2hvaWNlX2FuZF9sZWFybmluZ19wbG90cygiY2hvaWNlX2N1cnZlIikKYGBgCgoKIyMjIE5leHQgdHdvIHBsb3RzIGFyZSBzYW1lIGFzIHByZXZpb3VzIHR3bywgZXhjZXB0IGRpZmZpY3VsdHkgaGFzIGJlZW4gc2NhbGVkIGJldHdlZW4gMS0xMDAgcmF0aGVyIHRoYW4gYmVpbmcgaW4gcmF3IHVuaXRzCgpEaWZmaWN1bHR5IGlzIG1lYXN1cmVkIGhlcmUgYnkgc2NhbGVkIGJhc2VsaW5lIFJUCgpgYGB7ciBmaWcud2lkdGg9MTB9CgppbnB1dCRiYXRjaF9jaG9pY2VfY3VydmUgPC0gInJlcGxpY2F0aW9uIiAgICMgImV4cGxvcmF0b3J5IiAicmVwbGljYXRpb24iCmlucHV0JHlfdmFyX2Nob2ljZV9jdXJ2ZSA8LSAibXVsdCIgIyBhY2N1cmFjeSBiaWdnZXJfcmFuZCBiaWdnZXJfc2lkZSBiaWdnZXJfcmV3X2V4cG9zZWRfY3VtX21lYW4gYmlnZ2VyX3Jld19leHBvc2VkX2N1bV9jb3VudCBiaWdnZXJfcmV3X2xhdGVudCBiaWdnZXJfcmV3X2V4cG9zZWRfY3VtX3NkCmlucHV0JHhfcmF3X29yX3BlcmNlbnQgPC0gInBlcmNlbnQiICMgcmF3IHBlcmNlbnQKaW5wdXQkY2hvaWNlX2NvbWJvc19jaG9pY2VfY3VydmUgPC0gYygiTG9uZyBob3Jpem9uLCBmcmVlIGNob2ljZSAxIiwgIlNob3J0IGhvcml6b24sIGZyZWUgY2hvaWNlIDEiKSAjICJTaG9ydCBob3Jpem9uLCBmcmVlIGNob2ljZSAxIiAiTG9uZyBob3Jpem9uLCBmcmVlIGNob2ljZSAxIiAgIkxvbmcgaG9yaXpvbiwgZnJlZSBjaG9pY2UgMiIgICJMb25nIGhvcml6b24sIGZyZWUgY2hvaWNlIDMiICAiTG9uZyBob3Jpem9uLCBmcmVlIGNob2ljZSA0IiAgIkxvbmcgaG9yaXpvbiwgZnJlZSBjaG9pY2UgNSIKaW5wdXQkeF9jb21wYXJpc29uX2dyb3VwIDwtICJtdWx0IiAjIHJld19leHBvc2VkX2N1bV9zZCByZXdfZXhwb3NlZF9jdW1fbWVhbiByZXdfbGF0ZW50IHNpZGUgcmFuZAppbnB1dCR4X2NvbXBhcmlzb25fZGltZW5zaW9uIDwtICJydCIgIyByZXdfZXhwb3NlZF9jdW1fbWVhbiByZXdfbGF0ZW50IGRpZmZpY3VsdHkgcmFuZCByZXdfZXhwb3NlZF9jdW1fc2QKaW5wdXQkc2hvd19DSV9jaG9pY2VfY3VydmUgPC0gVCAjIEYKCmNob2ljZV9hbmRfbGVhcm5pbmdfcGxvdHMoImNob2ljZV9jdXJ2ZSIpCmBgYAoKRGlmZmljdWx0eSBpcyBtZWFzdXJlZCBoZXJlIGJ5IHNjYWxlZCBiYXNlbGluZSBzZWxmLXJhdGVkIGRpZmZpY3VsdHkKCmBgYHtyIGZpZy53aWR0aD0xMH0KCmlucHV0JGJhdGNoX2Nob2ljZV9jdXJ2ZSA8LSAicmVwbGljYXRpb24iICAgIyAiZXhwbG9yYXRvcnkiICJyZXBsaWNhdGlvbiIKaW5wdXQkeV92YXJfY2hvaWNlX2N1cnZlIDwtICJtdWx0IiAjIGFjY3VyYWN5IGJpZ2dlcl9yYW5kIGJpZ2dlcl9zaWRlIGJpZ2dlcl9yZXdfZXhwb3NlZF9jdW1fbWVhbiBiaWdnZXJfcmV3X2V4cG9zZWRfY3VtX2NvdW50IGJpZ2dlcl9yZXdfbGF0ZW50IGJpZ2dlcl9yZXdfZXhwb3NlZF9jdW1fc2QKaW5wdXQkeF9yYXdfb3JfcGVyY2VudCA8LSAicGVyY2VudCIgIyByYXcgcGVyY2VudAppbnB1dCRjaG9pY2VfY29tYm9zX2Nob2ljZV9jdXJ2ZSA8LSBjKCJMb25nIGhvcml6b24sIGZyZWUgY2hvaWNlIDEiLCAiU2hvcnQgaG9yaXpvbiwgZnJlZSBjaG9pY2UgMSIpICMgIlNob3J0IGhvcml6b24sIGZyZWUgY2hvaWNlIDEiICJMb25nIGhvcml6b24sIGZyZWUgY2hvaWNlIDEiICAiTG9uZyBob3Jpem9uLCBmcmVlIGNob2ljZSAyIiAgIkxvbmcgaG9yaXpvbiwgZnJlZSBjaG9pY2UgMyIgICJMb25nIGhvcml6b24sIGZyZWUgY2hvaWNlIDQiICAiTG9uZyBob3Jpem9uLCBmcmVlIGNob2ljZSA1IgppbnB1dCR4X2NvbXBhcmlzb25fZ3JvdXAgPC0gIm11bHQiICMgcmV3X2V4cG9zZWRfY3VtX3NkIHJld19leHBvc2VkX2N1bV9tZWFuIHJld19sYXRlbnQgc2lkZSByYW5kCmlucHV0JHhfY29tcGFyaXNvbl9kaW1lbnNpb24gPC0gImRpZmZpY3VsdHkiICMgcmV3X2V4cG9zZWRfY3VtX21lYW4gcmV3X2xhdGVudCBkaWZmaWN1bHR5IHJhbmQgcmV3X2V4cG9zZWRfY3VtX3NkCmlucHV0JHNob3dfQ0lfY2hvaWNlX2N1cnZlIDwtIFQgIyBGCgpjaG9pY2VfYW5kX2xlYXJuaW5nX3Bsb3RzKCJjaG9pY2VfY3VydmUiKQpgYGAKCgojIyMgUHJvYmFiaWxpdHkgb2YgY2hvb3NpbmcgbXVsdCBiYXNlZCBvbiBob3cgbXVjaCBtb3JlIG9yIGxlc3MgcmV3YXJkaW5nIChpbiBwb2ludHMpIGl0J3MgYmVlbiwgY29tcGFyZWQgdG8gYWRkaXRpb24gc2lkZQoKYGBge3IgZmlnLndpZHRoPTEwfQoKaW5wdXQkYmF0Y2hfY2hvaWNlX2N1cnZlIDwtICJyZXBsaWNhdGlvbiIgICAjICJleHBsb3JhdG9yeSIgInJlcGxpY2F0aW9uIgppbnB1dCR5X3Zhcl9jaG9pY2VfY3VydmUgPC0gIm11bHQiICMgbXVsdCBhY2N1cmFjeSBiaWdnZXJfcmFuZCBiaWdnZXJfc2lkZSBiaWdnZXJfcmV3X2V4cG9zZWRfY3VtX21lYW4gYmlnZ2VyX3Jld19leHBvc2VkX2N1bV9jb3VudCBiaWdnZXJfcmV3X2xhdGVudCBiaWdnZXJfcmV3X2V4cG9zZWRfY3VtX3NkCmlucHV0JHhfcmF3X29yX3BlcmNlbnQgPC0gInJhdyIgIyByYXcgcGVyY2VudAppbnB1dCRjaG9pY2VfY29tYm9zX2Nob2ljZV9jdXJ2ZSA8LSBjKCJMb25nIGhvcml6b24sIGZyZWUgY2hvaWNlIDEiLCAiU2hvcnQgaG9yaXpvbiwgZnJlZSBjaG9pY2UgMSIpICMgIlNob3J0IGhvcml6b24sIGZyZWUgY2hvaWNlIDEiICJMb25nIGhvcml6b24sIGZyZWUgY2hvaWNlIDEiICAiTG9uZyBob3Jpem9uLCBmcmVlIGNob2ljZSAyIiAgIkxvbmcgaG9yaXpvbiwgZnJlZSBjaG9pY2UgMyIgICJMb25nIGhvcml6b24sIGZyZWUgY2hvaWNlIDQiICAiTG9uZyBob3Jpem9uLCBmcmVlIGNob2ljZSA1IgppbnB1dCR4X2NvbXBhcmlzb25fZ3JvdXAgPC0gIm11bHQiICMgbXVsdCByZXdfZXhwb3NlZF9jdW1fc2QgcmV3X2V4cG9zZWRfY3VtX21lYW4gcmV3X2xhdGVudCBzaWRlIHJhbmQKaW5wdXQkeF9jb21wYXJpc29uX2RpbWVuc2lvbiA8LSAicmV3X2V4cG9zZWRfY3VtX21lYW4iICMgcnQgcmV3X2V4cG9zZWRfY3VtX21lYW4gcmV3X2xhdGVudCBkaWZmaWN1bHR5IHJhbmQgcmV3X2V4cG9zZWRfY3VtX3NkCmlucHV0JHNob3dfQ0lfY2hvaWNlX2N1cnZlIDwtIFQgIyBUIEYKY2hvaWNlX2FuZF9sZWFybmluZ19wbG90cygiY2hvaWNlX2N1cnZlIikKYGBgCgoKIyMgQ2hvaWNlIEN1cnZlcyAoZm9yIGV4cGxvcmF0b3J5IGRhdGEpCgojIyMgSG93IG11Y2ggaGFyZGVyIG11bHQgaXMgdGhhbiBhZGQgc2lkZSBhbmQgbGlrZWxpaG9vZCBvZiBjaG9vc2luZyBtdWx0CgpEaWZmaWN1bHR5IGlzIG1lYXN1cmVkIGhlcmUgYnkgcmF3IGJhc2VsaW5lIFJUCgpgYGB7ciBmaWcud2lkdGg9MTB9CgppbnB1dCA8LSBsaXN0KCkKCmlucHV0JGJhdGNoX2Nob2ljZV9jdXJ2ZSA8LSAiZXhwbG9yYXRvcnkiICAgIyAiZXhwbG9yYXRvcnkiICJyZXBsaWNhdGlvbiIKaW5wdXQkeV92YXJfY2hvaWNlX2N1cnZlIDwtICJtdWx0IiAjIGFjY3VyYWN5IGJpZ2dlcl9yYW5kIGJpZ2dlcl9zaWRlIGJpZ2dlcl9yZXdfZXhwb3NlZF9jdW1fbWVhbiBiaWdnZXJfcmV3X2V4cG9zZWRfY3VtX2NvdW50IGJpZ2dlcl9yZXdfbGF0ZW50IGJpZ2dlcl9yZXdfZXhwb3NlZF9jdW1fc2QKaW5wdXQkeF9yYXdfb3JfcGVyY2VudCA8LSAicmF3IiAjIHJhdyBwZXJjZW50CmlucHV0JGNob2ljZV9jb21ib3NfY2hvaWNlX2N1cnZlIDwtIGMoIkxvbmcgaG9yaXpvbiwgZnJlZSBjaG9pY2UgMSIsICJTaG9ydCBob3Jpem9uLCBmcmVlIGNob2ljZSAxIikgIyAiU2hvcnQgaG9yaXpvbiwgZnJlZSBjaG9pY2UgMSIgIkxvbmcgaG9yaXpvbiwgZnJlZSBjaG9pY2UgMSIgICJMb25nIGhvcml6b24sIGZyZWUgY2hvaWNlIDIiICAiTG9uZyBob3Jpem9uLCBmcmVlIGNob2ljZSAzIiAgIkxvbmcgaG9yaXpvbiwgZnJlZSBjaG9pY2UgNCIgICJMb25nIGhvcml6b24sIGZyZWUgY2hvaWNlIDUiCmlucHV0JHhfY29tcGFyaXNvbl9ncm91cCA8LSAibXVsdCIgIyByZXdfZXhwb3NlZF9jdW1fc2QgcmV3X2V4cG9zZWRfY3VtX21lYW4gcmV3X2xhdGVudCBzaWRlIHJhbmQKaW5wdXQkeF9jb21wYXJpc29uX2RpbWVuc2lvbiA8LSAicnQiICMgcmV3X2V4cG9zZWRfY3VtX21lYW4gcmV3X2xhdGVudCBkaWZmaWN1bHR5IHJhbmQgcmV3X2V4cG9zZWRfY3VtX3NkCmlucHV0JHNob3dfQ0lfY2hvaWNlX2N1cnZlIDwtIFQgIyBGCgpjaG9pY2VfYW5kX2xlYXJuaW5nX3Bsb3RzKCJjaG9pY2VfY3VydmUiKQpgYGAKCkRpZmZpY3VsdHkgaXMgbWVhc3VyZWQgaGVyZSBieSByYXcgYmFzZWxpbmUgc2VsZi1yYXRlZCBkaWZmaWN1bHR5CgpgYGB7ciBmaWcud2lkdGg9MTB9CgppbnB1dCRiYXRjaF9jaG9pY2VfY3VydmUgPC0gImV4cGxvcmF0b3J5IiAgICMgImV4cGxvcmF0b3J5IiAicmVwbGljYXRpb24iCmlucHV0JHlfdmFyX2Nob2ljZV9jdXJ2ZSA8LSAibXVsdCIgIyBhY2N1cmFjeSBiaWdnZXJfcmFuZCBiaWdnZXJfc2lkZSBiaWdnZXJfcmV3X2V4cG9zZWRfY3VtX21lYW4gYmlnZ2VyX3Jld19leHBvc2VkX2N1bV9jb3VudCBiaWdnZXJfcmV3X2xhdGVudCBiaWdnZXJfcmV3X2V4cG9zZWRfY3VtX3NkCmlucHV0JHhfcmF3X29yX3BlcmNlbnQgPC0gInJhdyIgIyByYXcgcGVyY2VudAppbnB1dCRjaG9pY2VfY29tYm9zX2Nob2ljZV9jdXJ2ZSA8LSBjKCJMb25nIGhvcml6b24sIGZyZWUgY2hvaWNlIDEiLCAiU2hvcnQgaG9yaXpvbiwgZnJlZSBjaG9pY2UgMSIpICMgIlNob3J0IGhvcml6b24sIGZyZWUgY2hvaWNlIDEiICJMb25nIGhvcml6b24sIGZyZWUgY2hvaWNlIDEiICAiTG9uZyBob3Jpem9uLCBmcmVlIGNob2ljZSAyIiAgIkxvbmcgaG9yaXpvbiwgZnJlZSBjaG9pY2UgMyIgICJMb25nIGhvcml6b24sIGZyZWUgY2hvaWNlIDQiICAiTG9uZyBob3Jpem9uLCBmcmVlIGNob2ljZSA1IgppbnB1dCR4X2NvbXBhcmlzb25fZ3JvdXAgPC0gIm11bHQiICMgcmV3X2V4cG9zZWRfY3VtX3NkIHJld19leHBvc2VkX2N1bV9tZWFuIHJld19sYXRlbnQgc2lkZSByYW5kCmlucHV0JHhfY29tcGFyaXNvbl9kaW1lbnNpb24gPC0gImRpZmZpY3VsdHkiICMgcmV3X2V4cG9zZWRfY3VtX21lYW4gcmV3X2xhdGVudCBkaWZmaWN1bHR5IHJhbmQgcmV3X2V4cG9zZWRfY3VtX3NkCmlucHV0JHNob3dfQ0lfY2hvaWNlX2N1cnZlIDwtIFQgIyBGCgpjaG9pY2VfYW5kX2xlYXJuaW5nX3Bsb3RzKCJjaG9pY2VfY3VydmUiKQpgYGAKCgojIyMgTmV4dCB0d28gcGxvdHMgYXJlIHNhbWUgYXMgcHJldmlvdXMgdHdvLCBleGNlcHQgZGlmZmljdWx0eSBoYXMgYmVlbiBzY2FsZWQgYmV0d2VlbiAxLTEwMCByYXRoZXIgdGhhbiBiZWluZyBpbiByYXcgdW5pdHMKCkRpZmZpY3VsdHkgaXMgbWVhc3VyZWQgaGVyZSBieSBzY2FsZWQgYmFzZWxpbmUgUlQKCmBgYHtyIGZpZy53aWR0aD0xMH0KCmlucHV0JGJhdGNoX2Nob2ljZV9jdXJ2ZSA8LSAiZXhwbG9yYXRvcnkiICAgIyAiZXhwbG9yYXRvcnkiICJyZXBsaWNhdGlvbiIKaW5wdXQkeV92YXJfY2hvaWNlX2N1cnZlIDwtICJtdWx0IiAjIGFjY3VyYWN5IGJpZ2dlcl9yYW5kIGJpZ2dlcl9zaWRlIGJpZ2dlcl9yZXdfZXhwb3NlZF9jdW1fbWVhbiBiaWdnZXJfcmV3X2V4cG9zZWRfY3VtX2NvdW50IGJpZ2dlcl9yZXdfbGF0ZW50IGJpZ2dlcl9yZXdfZXhwb3NlZF9jdW1fc2QKaW5wdXQkeF9yYXdfb3JfcGVyY2VudCA8LSAicGVyY2VudCIgIyByYXcgcGVyY2VudAppbnB1dCRjaG9pY2VfY29tYm9zX2Nob2ljZV9jdXJ2ZSA8LSBjKCJMb25nIGhvcml6b24sIGZyZWUgY2hvaWNlIDEiLCAiU2hvcnQgaG9yaXpvbiwgZnJlZSBjaG9pY2UgMSIpICMgIlNob3J0IGhvcml6b24sIGZyZWUgY2hvaWNlIDEiICJMb25nIGhvcml6b24sIGZyZWUgY2hvaWNlIDEiICAiTG9uZyBob3Jpem9uLCBmcmVlIGNob2ljZSAyIiAgIkxvbmcgaG9yaXpvbiwgZnJlZSBjaG9pY2UgMyIgICJMb25nIGhvcml6b24sIGZyZWUgY2hvaWNlIDQiICAiTG9uZyBob3Jpem9uLCBmcmVlIGNob2ljZSA1IgppbnB1dCR4X2NvbXBhcmlzb25fZ3JvdXAgPC0gIm11bHQiICMgcmV3X2V4cG9zZWRfY3VtX3NkIHJld19leHBvc2VkX2N1bV9tZWFuIHJld19sYXRlbnQgc2lkZSByYW5kCmlucHV0JHhfY29tcGFyaXNvbl9kaW1lbnNpb24gPC0gInJ0IiAjIHJld19leHBvc2VkX2N1bV9tZWFuIHJld19sYXRlbnQgZGlmZmljdWx0eSByYW5kIHJld19leHBvc2VkX2N1bV9zZAppbnB1dCRzaG93X0NJX2Nob2ljZV9jdXJ2ZSA8LSBUICMgRgoKY2hvaWNlX2FuZF9sZWFybmluZ19wbG90cygiY2hvaWNlX2N1cnZlIikKYGBgCgpEaWZmaWN1bHR5IGlzIG1lYXN1cmVkIGhlcmUgYnkgc2NhbGVkIGJhc2VsaW5lIHNlbGYtcmF0ZWQgZGlmZmljdWx0eQoKYGBge3IgZmlnLndpZHRoPTEwfQoKaW5wdXQkYmF0Y2hfY2hvaWNlX2N1cnZlIDwtICJleHBsb3JhdG9yeSIgICAjICJleHBsb3JhdG9yeSIgInJlcGxpY2F0aW9uIgppbnB1dCR5X3Zhcl9jaG9pY2VfY3VydmUgPC0gIm11bHQiICMgYWNjdXJhY3kgYmlnZ2VyX3JhbmQgYmlnZ2VyX3NpZGUgYmlnZ2VyX3Jld19leHBvc2VkX2N1bV9tZWFuIGJpZ2dlcl9yZXdfZXhwb3NlZF9jdW1fY291bnQgYmlnZ2VyX3Jld19sYXRlbnQgYmlnZ2VyX3Jld19leHBvc2VkX2N1bV9zZAppbnB1dCR4X3Jhd19vcl9wZXJjZW50IDwtICJwZXJjZW50IiAjIHJhdyBwZXJjZW50CmlucHV0JGNob2ljZV9jb21ib3NfY2hvaWNlX2N1cnZlIDwtIGMoIkxvbmcgaG9yaXpvbiwgZnJlZSBjaG9pY2UgMSIsICJTaG9ydCBob3Jpem9uLCBmcmVlIGNob2ljZSAxIikgIyAiU2hvcnQgaG9yaXpvbiwgZnJlZSBjaG9pY2UgMSIgIkxvbmcgaG9yaXpvbiwgZnJlZSBjaG9pY2UgMSIgICJMb25nIGhvcml6b24sIGZyZWUgY2hvaWNlIDIiICAiTG9uZyBob3Jpem9uLCBmcmVlIGNob2ljZSAzIiAgIkxvbmcgaG9yaXpvbiwgZnJlZSBjaG9pY2UgNCIgICJMb25nIGhvcml6b24sIGZyZWUgY2hvaWNlIDUiCmlucHV0JHhfY29tcGFyaXNvbl9ncm91cCA8LSAibXVsdCIgIyByZXdfZXhwb3NlZF9jdW1fc2QgcmV3X2V4cG9zZWRfY3VtX21lYW4gcmV3X2xhdGVudCBzaWRlIHJhbmQKaW5wdXQkeF9jb21wYXJpc29uX2RpbWVuc2lvbiA8LSAiZGlmZmljdWx0eSIgIyByZXdfZXhwb3NlZF9jdW1fbWVhbiByZXdfbGF0ZW50IGRpZmZpY3VsdHkgcmFuZCByZXdfZXhwb3NlZF9jdW1fc2QKaW5wdXQkc2hvd19DSV9jaG9pY2VfY3VydmUgPC0gVCAjIEYKCmNob2ljZV9hbmRfbGVhcm5pbmdfcGxvdHMoImNob2ljZV9jdXJ2ZSIpCmBgYAoKCiMjIyBQcm9iYWJpbGl0eSBvZiBjaG9vc2luZyBtdWx0IGJhc2VkIG9uIGhvdyBtdWNoIG1vcmUgb3IgbGVzcyByZXdhcmRpbmcgKGluIHBvaW50cykgaXQncyBiZWVuLCBjb21wYXJlZCB0byBhZGRpdGlvbiBzaWRlCgpgYGB7ciBmaWcud2lkdGg9MTB9CgppbnB1dCRiYXRjaF9jaG9pY2VfY3VydmUgPC0gImV4cGxvcmF0b3J5IiAgICMgImV4cGxvcmF0b3J5IiAicmVwbGljYXRpb24iCmlucHV0JHlfdmFyX2Nob2ljZV9jdXJ2ZSA8LSAibXVsdCIgIyBtdWx0IGFjY3VyYWN5IGJpZ2dlcl9yYW5kIGJpZ2dlcl9zaWRlIGJpZ2dlcl9yZXdfZXhwb3NlZF9jdW1fbWVhbiBiaWdnZXJfcmV3X2V4cG9zZWRfY3VtX2NvdW50IGJpZ2dlcl9yZXdfbGF0ZW50IGJpZ2dlcl9yZXdfZXhwb3NlZF9jdW1fc2QKaW5wdXQkeF9yYXdfb3JfcGVyY2VudCA8LSAicmF3IiAjIHJhdyBwZXJjZW50CmlucHV0JGNob2ljZV9jb21ib3NfY2hvaWNlX2N1cnZlIDwtIGMoIkxvbmcgaG9yaXpvbiwgZnJlZSBjaG9pY2UgMSIsICJTaG9ydCBob3Jpem9uLCBmcmVlIGNob2ljZSAxIikgIyAiU2hvcnQgaG9yaXpvbiwgZnJlZSBjaG9pY2UgMSIgIkxvbmcgaG9yaXpvbiwgZnJlZSBjaG9pY2UgMSIgICJMb25nIGhvcml6b24sIGZyZWUgY2hvaWNlIDIiICAiTG9uZyBob3Jpem9uLCBmcmVlIGNob2ljZSAzIiAgIkxvbmcgaG9yaXpvbiwgZnJlZSBjaG9pY2UgNCIgICJMb25nIGhvcml6b24sIGZyZWUgY2hvaWNlIDUiCmlucHV0JHhfY29tcGFyaXNvbl9ncm91cCA8LSAibXVsdCIgIyBtdWx0IHJld19leHBvc2VkX2N1bV9zZCByZXdfZXhwb3NlZF9jdW1fbWVhbiByZXdfbGF0ZW50IHNpZGUgcmFuZAppbnB1dCR4X2NvbXBhcmlzb25fZGltZW5zaW9uIDwtICJyZXdfZXhwb3NlZF9jdW1fbWVhbiIgIyBydCByZXdfZXhwb3NlZF9jdW1fbWVhbiByZXdfbGF0ZW50IGRpZmZpY3VsdHkgcmFuZCByZXdfZXhwb3NlZF9jdW1fc2QKaW5wdXQkc2hvd19DSV9jaG9pY2VfY3VydmUgPC0gVCAjIFQgRgpjaG9pY2VfYW5kX2xlYXJuaW5nX3Bsb3RzKCJjaG9pY2VfY3VydmUiKQpgYGAKCgo=